#region Using directives

/*
 * Copyright (c) 2007 Alan Dean.
 * All rights released.
 */

using System;
using System.Globalization;
using System.Security.Permissions;
using System.Threading;

using Edenbrook;

#endregion

namespace Edenbrook.Globalization
{
    #region Overview
    /// <summary>
    /// Provides functionality to obtain localized exceptions.
    /// <para>This class cannot be instantiated directly.</para>
    /// </summary>
    /// 
    /// <remarks>None</remarks>
    /// 
    /// <permission cref="T:System.Security.Permissions.StrongNameIdentityPermission">
    /// Callers must be signed with the Edenbrook strong name key.
    /// </permission>
    #endregion
    [StrongNameIdentityPermission(SecurityAction.Demand, PublicKey = PublicKey.Value)]
    public static class ExceptionFactory
    {
        // public static methods

        #region public static ArgumentOutOfRangeException ButtonNumber(string, int)
        /// <summary>
        /// Returns an <see cref="T:System.ArgumentOutOfRangeException"/> with the message:
        /// <para>The button value must be between 0 and 9, but {value} was specified.</para>
        /// </summary>
        /// 
        /// <param name="paramName">The name of the value that caused the exception.</param>
        /// <param name="value">The specified value.</param>
        /// 
        /// <returns>An <see cref="T:System.ArgumentOutOfRangeException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static ArgumentOutOfRangeException ButtonNumber(string paramName, int value)
        {
            CultureInfo culture = Thread.CurrentThread.CurrentUICulture;

            return new ArgumentOutOfRangeException(paramName,
                String.Format(
                    culture,
                    Properties.Resources.ExceptionFactoryButtonNumber,
                    value.ToString(culture)
                    )
                );
        }
        #endregion

        #region public static ArgumentOutOfRangeException CharNotDefined(string, char)
        /// <summary>
        /// Returns an <see cref="T:System.ArgumentOutOfRangeException"/> with the message:
        /// <para>The specified character, {value}, is not defined on this keypad.</para>
        /// </summary>
        /// 
        /// <param name="paramName">The name of the value that caused the exception.</param>
        /// <param name="value">The invalid character.</param>
        /// 
        /// <returns>An <see cref="T:System.ArgumentOutOfRangeException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static ArgumentOutOfRangeException CharNotDefined(string paramName, char value)
        {
            return new ArgumentOutOfRangeException(paramName,
                String.Format(
                    Thread.CurrentThread.CurrentUICulture,
                    Properties.Resources.ExceptionFactoryCharNotDefined,
                    value
                    )
                );
        }
        #endregion

        #region public static InvalidOperationException MessageLength(int)
        /// <summary>
        /// Returns an <see cref="T:System.InvalidOperationException"/> with the message:
        /// <para>The message cannot be longer than {maximumLength} characters.</para>
        /// </summary>
        /// 
        /// <param name="maximumLength">The maximum message length.</param>
        /// 
        /// <returns>An <see cref="T:System.InvalidOperationException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static InvalidOperationException MessageLength(int maximumLength)
        {
            CultureInfo culture = Thread.CurrentThread.CurrentUICulture;

            return new InvalidOperationException(
                String.Format(
                    culture,
                    Properties.Resources.ExceptionFactoryMessageLength,
                    maximumLength.ToString(culture)
                    )
                );
        }
        #endregion

        #region public static ArgumentOutOfRangeException NumberNegative(string, int)
        /// <summary>
        /// Returns an <see cref="T:System.ArgumentOutOfRangeException"/> with the message:
        /// <para>The value cannot be negative, but {value} was specified.</para>
        /// </summary>
        /// 
        /// <param name="paramName">The name of the value that caused the exception.</param>
        /// <param name="value">The specified value.</param>
        /// 
        /// <returns>An <see cref="T:System.ArgumentOutOfRangeException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static ArgumentOutOfRangeException NumberNegative(string paramName, int value)
        {
            CultureInfo culture = Thread.CurrentThread.CurrentUICulture;

            return new ArgumentOutOfRangeException(paramName,
                String.Format(
                    culture,
                    Properties.Resources.ExceptionFactoryNumberNegative,
                    value.ToString(culture)
                    )
                );
        }
        #endregion

        #region public static ArgumentOutOfRangeException ObjectMustBeOfType(string, Type)
        /// <summary>
        /// Returns an <see cref="T:System.ArgumentOutOfRangeException"/> with the message:
        /// <para>Object must be of type {expected.FullName}.</para>
        /// </summary>
        /// 
        /// <param name="paramName">The name of the value that caused the exception.</param>
        /// <param name="expected">The expected type.</param>
        /// 
        /// <returns>An <see cref="T:System.ArgumentOutOfRangeException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static ArgumentOutOfRangeException ObjectMustBeOfType(string paramName, Type expected)
        {
            return new ArgumentOutOfRangeException(paramName,
                String.Format(
                    Thread.CurrentThread.CurrentUICulture,
                    Properties.Resources.ExceptionFactoryObjectMustBeOfType,
                    expected == null ? "(null)" : expected.FullName
                    )
                );
        }
        #endregion

        #region public static ArgumentNullException ObjectNull(string)
        /// <summary>
        /// Returns an <see cref="T:System.ArgumentNullException"/> with the message:
        /// <para>{name} cannot be a null value.</para>
        /// </summary>
        /// 
        /// <param name="paramName">The name of the value that caused the exception.</param>
        /// 
        /// <returns>An <see cref="T:System.ArgumentNullException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static ArgumentNullException ObjectNull(string paramName)
        {
            return new ArgumentNullException(paramName,
                String.Format(
                    Thread.CurrentThread.CurrentUICulture,
                    Properties.Resources.ExceptionFactoryObjectNull,
                    String.IsNullOrEmpty(paramName) ? "(undefined)" : paramName
                    )
                );
        }
        #endregion

        #region public static ArgumentOutOfRangeException StringEmpty(string)
        /// <summary>
        /// Returns a <see cref="T:System.ArgumentOutOfRangeException"/> with the message:
        /// <para>{name} cannot be an empty string.</para>
        /// </summary>
        /// 
        /// <param name="paramName">The name of the value that caused the exception.</param>
        /// 
        /// <returns>An <see cref="T:System.ArgumentOutOfRangeException"/>.</returns>
        /// 
        /// <remarks>None</remarks>
        public static ArgumentOutOfRangeException StringEmpty(string paramName)
        {
            return new ArgumentOutOfRangeException(paramName,
                String.Format(
                    Thread.CurrentThread.CurrentUICulture,
                    Properties.Resources.ExceptionFactoryStringEmpty,
                    String.IsNullOrEmpty(paramName) ? "(undefined)" : paramName
                    )
                );
        }
        #endregion
    }
}